import glob
import math
import matplotlib.image as mpimg
import matplotlib.pyplot as plt
import numpy as np
import random
import sklearn.metrics as metrics
from tensorflow.keras import optimizers
from tensorflow.keras import backend
from tensorflow.keras.callbacks import ModelCheckpoint, CSVLogger, LearningRateScheduler
from tensorflow.keras.models import Model
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import add, concatenate, Conv2D, Dense, Dropout, Flatten, Input, Lambda, Reshape
from tensorflow.keras.layers import Activation, AveragePooling2D, BatchNormalization, MaxPooling2D, ZeroPadding2D
from tensorflow.keras.layers import GlobalAveragePooling2D
from tensorflow.keras.regularizers import l2
from tensorflow.keras.utils import to_categorical
%matplotlib inline
# Set up 'ggplot' style
plt.style.use('ggplot') # if want to use the default style, set 'classic'
plt.rcParams['ytick.right'] = True
plt.rcParams['ytick.labelright']= True
plt.rcParams['ytick.left'] = False
plt.rcParams['ytick.labelleft'] = False
plt.rcParams['font.family'] = 'Arial'
# where am i?
%pwd
%ls
flowers = glob.glob('./data/flr_*.jpg')
fungus = glob.glob('./data/fgs_*.jpg')
rocks = glob.glob('./data/rck_*.jpg')
pixel_flowers = glob.glob('./data/pxl_flower_*.jpeg')
pixel_umbrella = glob.glob('./data/pxl_umbrella_*.jpeg')
print("There are %s, %s flower, %s fungus, %s rock and %s umbrella pictures" %(len(flowers), len(pixel_flowers), len(fungus), len(rocks), len(pixel_umbrella)))
# Randomly show 10 examples of the images
from IPython.display import Image
dataset = flowers #flowers #fungus #rocks
for i in range(0, 5):
index = random.randint(0, len(dataset)-1)
print("Showing:", dataset[index])
img = mpimg.imread(dataset[index])
imgplot = plt.imshow(img)
plt.show()
#Image(dataset[index])
# Load the data
trDatOrg = np.load('npz/flrnonflr-train-imgs96-0.8+.npz')['arr_0']
trLblOrg = np.load('npz/flrnonflr-train-labels96-0.8+.npz')['arr_0']
tsDatOrg = np.load('npz/flrnonflr-test-imgs96-0.8+.npz')['arr_0']
tsLblOrg = np.load('npz/flrnonflr-test-labels96-0.8+.npz')['arr_0']
print("For the training and test datasets:")
print("The shapes are %s, %s, %s, %s" \
%(trDatOrg.shape, trLblOrg.shape, tsDatOrg.shape, tsLblOrg.shape))
# Randomly show 10 examples of the images
data = tsDatOrg
label = tsLblOrg
for i in range(20):
index = random.randint(0, len(data)-1)
print("Showing %s index image, It is %s" %(index, label[index]))
imgplot = plt.imshow(data[index])
plt.show()
# Convert the data into 'float32'
# Rescale the values from 0~255 to 0~1
trDat = trDatOrg.astype('float32')/255
tsDat = tsDatOrg.astype('float32')/255
# Retrieve the row size of each image
# Retrieve the column size of each image
imgrows = trDat.shape[1]
imgclms = trDat.shape[2]
channel = 3
# # reshape the data to be [samples][width][height][channel]
# # This is required by Keras framework
# trDat = trDat.reshape(trDat.shape[0], imgrows, imgclms, channel)
# tsDat = tsDat.reshape(tsDat.shape[0], imgrows, imgclms, channel)
# Perform one hot encoding on the labels
# Retrieve the number of classes in this problem
trLbl = to_categorical(trLblOrg)
tsLbl = to_categorical(tsLblOrg)
num_classes = tsLbl.shape[1]
# fix random seed for reproducibility
seed = 29
np.random.seed(seed)
modelname = 'FlowerPower'
#optmz = optimizers.Adam(lr=0.001)
optmz = optimizers.RMSprop(lr=0.001)
# Baseline Model -> func: createBaselineModel()
def createBaselineModel():
inputs = Input(shape=(imgrows, imgclms, channel))
x = Conv2D(30, (4, 4), activation='relu')(inputs)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Conv2D(50, (4, 4), activation='relu')(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Dropout(0.3)(x)
x = Flatten()(x)
x = Dense(32, activation='relu')(x)
x = Dense(num_classes, activation='softmax')(x)
model = Model(inputs=[inputs],outputs=x)
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
return model
# ResNetV1 -> func: createResNetV1()
def resLyr(inputs,
numFilters=16,
kernelSz=3,
strides=1,
activation='relu',
batchNorm=True,
convFirst=True,
lyrName=None):
convLyr = Conv2D(numFilters, kernel_size=kernelSz, strides=strides,
padding='same', kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4),
name=lyrName+'_conv' if lyrName else None)
x = inputs
if convFirst:
x = convLyr(x)
if batchNorm:
x = BatchNormalization(name=lyrName+'_bn' if lyrName else None)(x)
if activation is not None:
x = Activation(activation,name=lyrName+'_'+activation if lyrName else None)(x)
else:
if batchNorm:
x = BatchNormalization(name=lyrName+'_bn' if lyrName else None)(x)
if activation is not None:
x = Activation(activation, name=lyrName+'_'+activation if lyrName else None)(x)
x = convLyr(x)
return x
def resBlkV1(inputs,
numFilters=16,
numBlocks=3,
downsampleOnFirst=True,
names=None):
x = inputs
for run in range(0,numBlocks):
strides = 1
blkStr = str(run+1)
if downsampleOnFirst and run == 0:
strides = 2
y = resLyr(inputs=x, numFilters=numFilters, strides=strides,
lyrName=names+'_Blk'+blkStr+'_Res1' if names else None)
y = resLyr(inputs=y, numFilters=numFilters, activation=None,
lyrName=names+'_Blk'+blkStr+'_Res2' if names else None)
if downsampleOnFirst and run == 0:
x = resLyr(inputs=x, numFilters=numFilters, kernelSz=1,
strides=strides, activation=None, batchNorm=False,
lyrName=names+'_Blk'+blkStr+'_lin' if names else None)
x = add([x,y], name=names+'_Blk'+blkStr+'_add' if names else None)
x = Activation('relu', name=names+'_Blk'+blkStr+'_relu' if names else None)(x)
return x
def createResNetV1(inputShape=(imgrows, imgclms, channel),
numClasses=2):
inputs = Input(shape=inputShape)
v = resLyr(inputs, lyrName='Inpt')
v = resBlkV1(inputs=v, numFilters=16, numBlocks=3,
downsampleOnFirst=False, names='Stg1')
v = Dropout(0.30)(v)
v = resBlkV1(inputs=v, numFilters=32, numBlocks=3,
downsampleOnFirst=True, names='Stg2')
v = Dropout(0.40)(v)
v = resBlkV1(inputs=v, numFilters=64, numBlocks=3,
downsampleOnFirst=True, names='Stg3')
v = Dropout(0.50)(v)
v = resBlkV1(inputs=v, numFilters=128, numBlocks=3,
downsampleOnFirst=True, names='Stg4')
v = Dropout(0.50)(v)
v = resBlkV1(inputs=v, numFilters=128, numBlocks=3,
downsampleOnFirst=False, names='Stg5')
v = Dropout(0.50)(v)
v = resBlkV1(inputs=v, numFilters=256, numBlocks=3,
downsampleOnFirst=True, names='Stg6')
v = Dropout(0.50)(v)
v = AveragePooling2D(pool_size=6, name='AvgPool')(v)
v = Flatten()(v)
outputs = Dense(numClasses, activation='softmax',
kernel_initializer='he_normal')(v)
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss='categorical_crossentropy',
optimizer=optmz,
metrics=['accuracy'])
return model
# Mostly Original # Inception-v4 -> func: create_inception_v4()
def stem_block(inputs,
names=None):
x = inputs
x = Conv2D(filters=32, kernel_size=(3, 3), strides=2, padding='valid')(inputs)
x = Conv2D(filters=32, kernel_size=(3, 3), strides=1, padding='valid')(x)
x = Conv2D(filters=64, kernel_size=(3, 3), strides=1, padding='same')(x)
x_L1_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_R1_1 = Conv2D(filters=96, kernel_size=(3, 3), strides=2, padding='valid')(x)
x = concatenate([x_L1_1, x_R1_1])
x_L2_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_L2_2 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(x_L2_1)
x_R2_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R2_2 = Conv2D(filters=64, kernel_size=(7, 1), strides=1, padding='same')(x_R2_1)
x_R2_3 = Conv2D(filters=64, kernel_size=(1, 7), strides=1, padding='same')(x_R2_2)
x_R2_4 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(x_R2_3)
x = concatenate([x_L2_2, x_R2_4])
x_L3_1 = Conv2D(filters=192, kernel_size=(3, 3), strides=2, padding='valid')(x)
x_L3_2 = ZeroPadding2D(padding=((0,1), (0,1)))(x_L3_1) # Added due to size mismatch
x_R3_1 = MaxPooling2D(strides=2, padding='valid')(x)
x = concatenate([x_L3_2, x_R3_1])
return x
def inception_a_block(inputs,
names=None):
x = inputs
x_EL1_1 = AveragePooling2D(pool_size=(1, 1), padding='same')(x)
x_EL1_2 = Conv2D(filters=96, kernel_size=(1, 1), strides=1, padding='same')(x_EL1_1)
x_ML1_1 = Conv2D(filters=96, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_2 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='same')(x_MR1_1)
x_ER1_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ER1_2 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='same')(x_ER1_1)
x_ER1_3 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='same')(x_ER1_2)
x = concatenate([x_EL1_2, x_ML1_1, x_MR1_2, x_ER1_3])
return x
def inception_b_block(inputs,
names=None):
x = inputs
x_EL1_1 = AveragePooling2D(pool_size=(1, 1), padding='same')(x)
x_EL1_2 = Conv2D(filters=128, kernel_size=(1, 1), strides=1, padding='same')(x_EL1_1)
x_ML1_1 = Conv2D(filters=384, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_1 = Conv2D(filters=192, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_2 = Conv2D(filters=224, kernel_size=(1, 7), strides=1, padding='same')(x_MR1_1)
x_MR1_3 = Conv2D(filters=256, kernel_size=(1, 7), strides=1, padding='same')(x_MR1_2)
x_ER1_1 = Conv2D(filters=192, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ER1_2 = Conv2D(filters=192, kernel_size=(1, 7), strides=1, padding='same')(x_ER1_1)
x_ER1_3 = Conv2D(filters=224, kernel_size=(7, 1), strides=1, padding='same')(x_ER1_2)
x_ER1_4 = Conv2D(filters=224, kernel_size=(1, 7), strides=1, padding='same')(x_ER1_3)
x_ER1_5 = Conv2D(filters=256, kernel_size=(7, 1), strides=1, padding='same')(x_ER1_4)
x = concatenate([x_EL1_2, x_ML1_1, x_MR1_3, x_ER1_5])
return x
def inception_c_block(inputs,
names=None):
x = inputs
x_EL1_1 = AveragePooling2D(pool_size=(1, 1), padding='same')(x)
x_EL1_2 = Conv2D(filters=256, kernel_size=(1, 1), strides=1, padding='same')(x_EL1_1)
x_ML1_1 = Conv2D(filters=256, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_1 = Conv2D(filters=384, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_1_L2 = Conv2D(filters=256, kernel_size=(1, 3), strides=1, padding='same')(x_MR1_1)
x_MR1_1_R2 = Conv2D(filters=256, kernel_size=(3, 1), strides=1, padding='same')(x_MR1_1)
x_ER1_1 = Conv2D(filters=384, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ER1_2 = Conv2D(filters=448, kernel_size=(1, 3), strides=1, padding='same')(x_ER1_1)
x_ER1_3 = Conv2D(filters=512, kernel_size=(3, 1), strides=1, padding='same')(x_ER1_2)
x_ER1_3_L1 = Conv2D(filters=256, kernel_size=(3, 1), strides=1, padding='same')(x_ER1_3)
x_ER1_3_R1 = Conv2D(filters=256, kernel_size=(1, 3), strides=1, padding='same')(x_ER1_3)
x = concatenate([x_EL1_2, x_ML1_1, x_MR1_1_L2, x_MR1_1_R2, x_ER1_3_L1, x_ER1_3_R1])
return x
def reduction_a_block(inputs,
network_selected="Inception-v4",
names=None):
if network_selected == "Inception-v4":
k, l, m, n = 192, 224, 256, 384
elif network_selected == "Inception-ResNet-v1":
k, l, m, n = 192, 192, 256, 384
elif network_selected == "Inception-ResNet-v2":
k, l, m, n = 256, 256, 384, 384
x = inputs
x_L_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_M_1 = Conv2D(filters=n, kernel_size=(3, 3), strides=2, padding='valid')(x)
x_R_1 = Conv2D(filters=k, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=l, kernel_size=(3, 3), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=m, kernel_size=(3, 3), strides=2, padding='valid')(x_R_2)
x = concatenate([x_L_1, x_M_1, x_R_3])
return x
def reduction_b_block(inputs,
names=None):
x = inputs
x_L_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_M_1 = Conv2D(filters=192, kernel_size=(1, 1), strides=1, padding='same')(x)
x_M_2 = Conv2D(filters=192, kernel_size=(3, 3), strides=2, padding='valid')(x_M_1)
x_R_1 = Conv2D(filters=256, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=256, kernel_size=(1, 7), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=320, kernel_size=(7, 1), strides=1, padding='same')(x_R_2)
x_R_4 = Conv2D(filters=320, kernel_size=(3, 3), strides=2, padding='valid')(x_R_3)
x = concatenate([x_L_1, x_M_2, x_R_4])
return x
def create_inception_v4(inputShape=(imgrows, imgclms, channel),
num_classes=2):
NETWORK_SELECTED = "Inception-v4"
inputs = Input(shape=inputShape)
x = stem_block(inputs)
x = inception_a_block(x)
x = inception_a_block(x)
x = inception_a_block(x)
x = inception_a_block(x)
x = reduction_a_block(x, network_selected=NETWORK_SELECTED)
x = inception_b_block(x)
x = inception_b_block(x)
x = inception_b_block(x)
x = inception_b_block(x)
x = inception_b_block(x)
x = inception_b_block(x)
x = inception_b_block(x)
x = reduction_b_block(x)
x = inception_c_block(x)
x = inception_c_block(x)
x = inception_c_block(x)
x = AveragePooling2D(pool_size=(1,1))(x) # Added (1,1) due to negative dimension
x = Flatten()(x)
x = Dense(1536)(x) # Changed
x = Dropout(0.2)(x)
outputs = Dense(num_classes, activation='softmax',
kernel_initializer='he_normal')(x)
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss='categorical_crossentropy',
optimizer="Adam",
metrics=['accuracy'])
return model
# Modified2 # Inception-v4 -> func: create_inception_v4()
def stem_block(inputs,
names=None):
x = inputs
x = Conv2D(filters=32, kernel_size=(3, 3), strides=2, padding='valid')(inputs)
x = Conv2D(filters=32, kernel_size=(3, 3), strides=1, padding='valid')(x)
x = Conv2D(filters=64, kernel_size=(3, 3), strides=1, padding='same')(x)
x_L1_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_R1_1 = Conv2D(filters=96, kernel_size=(3, 3), strides=2, padding='valid')(x)
x = concatenate([x_L1_1, x_R1_1])
x_L2_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_L2_2 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(x_L2_1)
x_R2_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R2_2 = Conv2D(filters=64, kernel_size=(7, 1), strides=1, padding='same')(x_R2_1)
x_R2_3 = Conv2D(filters=64, kernel_size=(1, 7), strides=1, padding='same')(x_R2_2)
x_R2_4 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(x_R2_3)
x = concatenate([x_L2_2, x_R2_4])
x_L3_1 = Conv2D(filters=192, kernel_size=(3, 3), strides=2, padding='valid')(x)
x_L3_2 = ZeroPadding2D(padding=((0,1), (0,1)))(x_L3_1) # Added due to size mismatch
x_R3_1 = MaxPooling2D(strides=2, padding='valid')(x)
x = concatenate([x_L3_2, x_R3_1])
return x
def inception_a_block(inputs,
names=None):
x = inputs
x_EL1_1 = AveragePooling2D(pool_size=(1, 1), padding='same')(x)
x_EL1_2 = Conv2D(filters=96, kernel_size=(1, 1), strides=1, padding='same')(x_EL1_1)
x_ML1_1 = Conv2D(filters=96, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_2 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='same')(x_MR1_1)
x_ER1_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ER1_2 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='same')(x_ER1_1)
x_ER1_3 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='same')(x_ER1_2)
x = concatenate([x_EL1_2, x_ML1_1, x_MR1_2, x_ER1_3])
return x
def inception_b_block(inputs,
names=None):
x = inputs
x_EL1_1 = AveragePooling2D(pool_size=(1, 1), padding='same')(x)
x_EL1_2 = Conv2D(filters=128, kernel_size=(1, 1), strides=1, padding='same')(x_EL1_1)
x_ML1_1 = Conv2D(filters=384, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_1 = Conv2D(filters=192, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_2 = Conv2D(filters=224, kernel_size=(1, 7), strides=1, padding='same')(x_MR1_1)
x_MR1_3 = Conv2D(filters=256, kernel_size=(1, 7), strides=1, padding='same')(x_MR1_2)
x_ER1_1 = Conv2D(filters=192, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ER1_2 = Conv2D(filters=192, kernel_size=(1, 7), strides=1, padding='same')(x_ER1_1)
x_ER1_3 = Conv2D(filters=224, kernel_size=(7, 1), strides=1, padding='same')(x_ER1_2)
x_ER1_4 = Conv2D(filters=224, kernel_size=(1, 7), strides=1, padding='same')(x_ER1_3)
x_ER1_5 = Conv2D(filters=256, kernel_size=(7, 1), strides=1, padding='same')(x_ER1_4)
x = concatenate([x_EL1_2, x_ML1_1, x_MR1_3, x_ER1_5])
return x
def inception_c_block(inputs,
names=None):
x = inputs
x_EL1_1 = AveragePooling2D(pool_size=(1, 1), padding='same')(x)
x_EL1_2 = Conv2D(filters=256, kernel_size=(1, 1), strides=1, padding='same')(x_EL1_1)
x_ML1_1 = Conv2D(filters=256, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_1 = Conv2D(filters=384, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_1_L2 = Conv2D(filters=256, kernel_size=(1, 3), strides=1, padding='same')(x_MR1_1)
x_MR1_1_R2 = Conv2D(filters=256, kernel_size=(3, 1), strides=1, padding='same')(x_MR1_1)
x_ER1_1 = Conv2D(filters=384, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ER1_2 = Conv2D(filters=448, kernel_size=(1, 3), strides=1, padding='same')(x_ER1_1)
x_ER1_3 = Conv2D(filters=512, kernel_size=(3, 1), strides=1, padding='same')(x_ER1_2)
x_ER1_3_L1 = Conv2D(filters=256, kernel_size=(3, 1), strides=1, padding='same')(x_ER1_3)
x_ER1_3_R1 = Conv2D(filters=256, kernel_size=(1, 3), strides=1, padding='same')(x_ER1_3)
x = concatenate([x_EL1_2, x_ML1_1, x_MR1_1_L2, x_MR1_1_R2, x_ER1_3_L1, x_ER1_3_R1])
return x
def reduction_a_block(inputs,
network_selected="Inception-v4",
names=None):
if network_selected == "Inception-v4":
k, l, m, n = 192, 224, 256, 384
elif network_selected == "Inception-ResNet-v1":
k, l, m, n = 192, 192, 256, 384
elif network_selected == "Inception-ResNet-v2":
k, l, m, n = 256, 256, 384, 384
x = inputs
x_L_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_M_1 = Conv2D(filters=n, kernel_size=(3, 3), strides=2, padding='valid')(x)
x_R_1 = Conv2D(filters=k, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=l, kernel_size=(3, 3), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=m, kernel_size=(3, 3), strides=2, padding='valid')(x_R_2)
x = concatenate([x_L_1, x_M_1, x_R_3])
return x
def reduction_b_block(inputs,
names=None):
x = inputs
x_L_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_M_1 = Conv2D(filters=192, kernel_size=(1, 1), strides=1, padding='same')(x)
x_M_2 = Conv2D(filters=192, kernel_size=(3, 3), strides=2, padding='valid')(x_M_1)
x_R_1 = Conv2D(filters=256, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=256, kernel_size=(1, 7), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=320, kernel_size=(7, 1), strides=1, padding='same')(x_R_2)
x_R_4 = Conv2D(filters=320, kernel_size=(3, 3), strides=2, padding='valid')(x_R_3)
x = concatenate([x_L_1, x_M_2, x_R_4])
return x
def create_inception_v4(inputShape=(imgrows, imgclms, channel),
num_classes=2):
NETWORK_SELECTED = "Inception-v4"
inputs = Input(shape=inputShape)
x = stem_block(inputs)
x = BatchNormalization()(x)
x = inception_a_block(x)
x = BatchNormalization()(x)
x = inception_a_block(x)
x = BatchNormalization()(x)
x = inception_a_block(x)
x = BatchNormalization()(x)
x = inception_a_block(x)
x = BatchNormalization()(x)
x = reduction_a_block(x, network_selected=NETWORK_SELECTED)
x = BatchNormalization()(x)
x = inception_b_block(x)
x = BatchNormalization()(x)
x = inception_b_block(x)
x = BatchNormalization()(x)
x = inception_b_block(x)
x = BatchNormalization()(x)
x = inception_b_block(x)
x = BatchNormalization()(x)
x = inception_b_block(x)
x = BatchNormalization()(x)
x = inception_b_block(x)
x = BatchNormalization()(x)
x = inception_b_block(x)
x = BatchNormalization()(x)
x = reduction_b_block(x)
x = BatchNormalization()(x)
x = inception_c_block(x)
x = BatchNormalization()(x)
x = inception_c_block(x)
x = BatchNormalization()(x)
x = inception_c_block(x)
x = AveragePooling2D(pool_size=(1,1))(x) # Added (1,1) due to negative dimension
x = Flatten()(x)
x = Dense(1536)(x) # Changed
x = Dropout(0.2)(x)
outputs = Dense(num_classes, activation='softmax',
kernel_initializer='he_normal')(x)
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss='categorical_crossentropy',
optimizer="Adam",
metrics=['accuracy'])
return model
# Modified #(halfed) # Inception-v4 -> func: create_inception_v4()
def stem_block(inputs,
names=None):
x = inputs
x = Conv2D(filters=16, kernel_size=(3, 3), strides=2, padding='valid')(inputs)
x = Conv2D(filters=16, kernel_size=(3, 3), strides=1, padding='valid')(x)
x = Conv2D(filters=32, kernel_size=(3, 3), strides=1, padding='same')(x)
x_L1_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_R1_1 = Conv2D(filters=48, kernel_size=(3, 3), strides=2, padding='valid')(x)
x = concatenate([x_L1_1, x_R1_1])
x_L2_1 = Conv2D(filters=32, kernel_size=(1, 1), strides=1, padding='same')(x)
x_L2_2 = Conv2D(filters=48, kernel_size=(3, 3), strides=1, padding='valid')(x_L2_1)
x_R2_1 = Conv2D(filters=32, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R2_2 = Conv2D(filters=32, kernel_size=(7, 1), strides=1, padding='same')(x_R2_1)
x_R2_3 = Conv2D(filters=32, kernel_size=(1, 7), strides=1, padding='same')(x_R2_2)
x_R2_4 = Conv2D(filters=48, kernel_size=(3, 3), strides=1, padding='valid')(x_R2_3)
x = concatenate([x_L2_2, x_R2_4])
x_L3_1 = Conv2D(filters=96, kernel_size=(3, 3), strides=2, padding='valid')(x)
x_L3_2 = ZeroPadding2D(padding=((0,1), (0,1)))(x_L3_1) # Added due to size mismatch
x_R3_1 = MaxPooling2D(strides=2, padding='valid')(x)
x = concatenate([x_L3_2, x_R3_1])
return x
def inception_a_block(inputs,
names=None):
x = inputs
x_EL1_1 = AveragePooling2D(pool_size=(1, 1), padding='same')(x)
x_EL1_2 = Conv2D(filters=48, kernel_size=(1, 1), strides=1, padding='same')(x_EL1_1)
x_ML1_1 = Conv2D(filters=48, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_1 = Conv2D(filters=32, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_2 = Conv2D(filters=48, kernel_size=(3, 3), strides=1, padding='same')(x_MR1_1)
x_ER1_1 = Conv2D(filters=32, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ER1_2 = Conv2D(filters=48, kernel_size=(3, 3), strides=1, padding='same')(x_ER1_1)
x_ER1_3 = Conv2D(filters=48, kernel_size=(3, 3), strides=1, padding='same')(x_ER1_2)
x = concatenate([x_EL1_2, x_ML1_1, x_MR1_2, x_ER1_3])
return x
def inception_b_block(inputs,
names=None):
x = inputs
x_EL1_1 = AveragePooling2D(pool_size=(1, 1), padding='same')(x)
x_EL1_2 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x_EL1_1)
x_ML1_1 = Conv2D(filters=192, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_1 = Conv2D(filters=96, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_2 = Conv2D(filters=112, kernel_size=(1, 7), strides=1, padding='same')(x_MR1_1)
x_MR1_3 = Conv2D(filters=128, kernel_size=(1, 7), strides=1, padding='same')(x_MR1_2)
x_ER1_1 = Conv2D(filters=96, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ER1_2 = Conv2D(filters=96, kernel_size=(1, 7), strides=1, padding='same')(x_ER1_1)
x_ER1_3 = Conv2D(filters=112, kernel_size=(7, 1), strides=1, padding='same')(x_ER1_2)
x_ER1_4 = Conv2D(filters=112, kernel_size=(1, 7), strides=1, padding='same')(x_ER1_3)
x_ER1_5 = Conv2D(filters=128, kernel_size=(7, 1), strides=1, padding='same')(x_ER1_4)
x = concatenate([x_EL1_2, x_ML1_1, x_MR1_3, x_ER1_5])
return x
def inception_c_block(inputs,
names=None):
x = inputs
x_EL1_1 = AveragePooling2D(pool_size=(1, 1), padding='same')(x)
x_EL1_2 = Conv2D(filters=128, kernel_size=(1, 1), strides=1, padding='same')(x_EL1_1)
x_ML1_1 = Conv2D(filters=128, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_1 = Conv2D(filters=192, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR1_1_L2 = Conv2D(filters=128, kernel_size=(1, 3), strides=1, padding='same')(x_MR1_1)
x_MR1_1_R2 = Conv2D(filters=128, kernel_size=(3, 1), strides=1, padding='same')(x_MR1_1)
x_ER1_1 = Conv2D(filters=192, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ER1_2 = Conv2D(filters=224, kernel_size=(1, 3), strides=1, padding='same')(x_ER1_1)
x_ER1_3 = Conv2D(filters=256, kernel_size=(3, 1), strides=1, padding='same')(x_ER1_2)
x_ER1_3_L1 = Conv2D(filters=128, kernel_size=(3, 1), strides=1, padding='same')(x_ER1_3)
x_ER1_3_R1 = Conv2D(filters=128, kernel_size=(1, 3), strides=1, padding='same')(x_ER1_3)
x = concatenate([x_EL1_2, x_ML1_1, x_MR1_1_L2, x_MR1_1_R2, x_ER1_3_L1, x_ER1_3_R1])
return x
def reduction_a_block(inputs,
network_selected="Inception-v4",
names=None):
if network_selected == "Inception-v4":
k, l, m, n = 192, 224, 256, 384
elif network_selected == "Inception-ResNet-v1":
k, l, m, n = 96, 96, 128, 192
elif network_selected == "Inception-ResNet-v2":
k, l, m, n = 128, 128, 192, 192
x = inputs
x_L_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_M_1 = Conv2D(filters=n, kernel_size=(3, 3), strides=2, padding='valid')(x)
x_R_1 = Conv2D(filters=k, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=l, kernel_size=(3, 3), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=m, kernel_size=(3, 3), strides=2, padding='valid')(x_R_2)
x = concatenate([x_L_1, x_M_1, x_R_3])
return x
def reduction_b_block(inputs,
names=None):
x = inputs
x_L_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_M_1 = Conv2D(filters=96, kernel_size=(1, 1), strides=1, padding='same')(x)
x_M_2 = Conv2D(filters=96, kernel_size=(3, 3), strides=2, padding='valid')(x_M_1)
x_R_1 = Conv2D(filters=128, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=128, kernel_size=(1, 7), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=160, kernel_size=(7, 1), strides=1, padding='same')(x_R_2)
x_R_4 = Conv2D(filters=160, kernel_size=(3, 3), strides=2, padding='valid')(x_R_3)
x = concatenate([x_L_1, x_M_2, x_R_4])
return x
def create_inception_v4(inputShape=(imgrows, imgclms, channel),
num_classes=2):
NETWORK_SELECTED = "Inception-v4"
inputs = Input(shape=inputShape)
x = stem_block(inputs)
x = BatchNormalization()(x)
x = inception_a_block(x)
x = BatchNormalization()(x)
x = inception_a_block(x)
x = BatchNormalization()(x)
x = inception_a_block(x)
x = BatchNormalization()(x)
x = inception_a_block(x)
x = BatchNormalization()(x)
x = reduction_a_block(x, network_selected=NETWORK_SELECTED)
x = BatchNormalization()(x)
x = inception_b_block(x)
x = BatchNormalization()(x)
x = inception_b_block(x)
x = BatchNormalization()(x)
x = inception_b_block(x)
x = BatchNormalization()(x)
x = inception_b_block(x)
x = BatchNormalization()(x)
x = inception_b_block(x)
x = BatchNormalization()(x)
x = inception_b_block(x)
x = BatchNormalization()(x)
x = inception_b_block(x)
x = BatchNormalization()(x)
x = reduction_b_block(x)
x = BatchNormalization()(x)
x = inception_c_block(x)
x = BatchNormalization()(x)
x = inception_c_block(x)
x = BatchNormalization()(x)
x = inception_c_block(x)
x = BatchNormalization()(x)
x = AveragePooling2D(pool_size=(1,1))(x) # Added (1,1) due to negative dimension
x = Flatten()(x)
x = Dense(256)(x)
x = Dropout(0.2)(x)
outputs = Dense(num_classes, activation='softmax',
kernel_initializer='he_normal')(x)
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss='categorical_crossentropy',
optimizer=optmz,
metrics=['accuracy'])
return model
# Mostly Original # Inception-Res-v2 -> func: create_inception_resnet_v2()
def stem_block(inputs,
names=None):
x = inputs
x = Conv2D(filters=32, kernel_size=(3, 3), strides=2, padding='valid')(inputs)
x = Conv2D(filters=32, kernel_size=(3, 3), strides=1, padding='valid')(x)
x = Conv2D(filters=64, kernel_size=(3, 3), strides=1, padding='same')(x)
x_L1_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_R1_1 = Conv2D(filters=96, kernel_size=(3, 3), strides=2, padding='valid')(x)
x = concatenate([x_L1_1, x_R1_1])
x_L2_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_L2_2 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(x_L2_1)
x_R2_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R2_2 = Conv2D(filters=64, kernel_size=(7, 1), strides=1, padding='same')(x_R2_1)
x_R2_3 = Conv2D(filters=64, kernel_size=(1, 7), strides=1, padding='same')(x_R2_2)
x_R2_4 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(x_R2_3)
x = concatenate([x_L2_2, x_R2_4])
x_L3_1 = Conv2D(filters=192, kernel_size=(3, 3), strides=2, padding='valid')(x)
x_L3_2 = ZeroPadding2D(padding=((0,1), (0,1)))(x_L3_1) # Added due to size mismatch
x_R3_1 = MaxPooling2D(strides=2, padding='valid')(x)
x = concatenate([x_L3_2, x_R3_1])
return x
def inception_resnet_v2_a_block(inputs,
scale=0.1,
names=None):
x = inputs
x_L_1 = Conv2D(filters=32, kernel_size=(1, 1), strides=1, padding='same')(x)
x_M_1 = Conv2D(filters=32, kernel_size=(1, 1), strides=1, padding='same')(x)
x_M_2 = Conv2D(filters=32, kernel_size=(3, 3), strides=1, padding='same')(x_M_1)
x_R_1 = Conv2D(filters=32, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=48, kernel_size=(3, 3), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=64, kernel_size=(3, 3), strides=1, padding='same')(x_R_2)
x_C_1 = concatenate([x_L_1, x_M_2, x_R_3])
x_C_2 = Conv2D(filters=384, kernel_size=(1, 1), padding='same', activation='linear')(x_C_1)
x = Lambda(lambda ipt, scale: ipt[0] + ipt[1] * scale,
output_shape=backend.int_shape(x)[1:],
arguments={'scale': scale})([x, x_C_2])
x = Activation(activation='relu')(x)
return x
def inception_resnet_v2_b_block(inputs,
scale=0.1,
names=None):
x = inputs
x_L_1 = Conv2D(filters=192, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_1 = Conv2D(filters=128, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=160, kernel_size=(1, 7), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=192, kernel_size=(7, 1), strides=1, padding='same')(x_R_2)
x_C_1 = concatenate([x_L_1, x_R_3])
x_C_2 = Conv2D(filters=1152, kernel_size=(1, 1), padding='same', activation='linear')(x_C_1)
x = Lambda(lambda ipt, scale: ipt[0] + ipt[1] * scale,
output_shape=backend.int_shape(x)[1:],
arguments={'scale': scale})([x, x_C_2])
x = Activation(activation='relu')(x)
return x
def inception_resnet_v2_c_block(inputs,
scale=0.1,
names=None):
x = inputs
x_L_1 = Conv2D(filters=192, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_1 = Conv2D(filters=192, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=224, kernel_size=(1, 3), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=256, kernel_size=(3, 1), strides=1, padding='same')(x_R_2)
x_C_1 = concatenate([x_L_1, x_R_3])
x_C_2 = Conv2D(filters=2048, kernel_size=(1, 1), padding='same', activation='linear')(x_C_1)
x = Lambda(lambda ipt, scale: ipt[0] + ipt[1] * scale,
output_shape=backend.int_shape(x)[1:],
arguments={'scale': scale})([x, x_C_2])
x = Activation(activation='relu')(x)
return x
def reduction_a_block(inputs,
network_selected="Inception-v4",
names=None):
if network_selected == "Inception-v4":
k, l, m, n = 192, 224, 256, 384
elif network_selected == "Inception-ResNet-v1":
k, l, m, n = 192, 192, 256, 384
elif network_selected == "Inception-ResNet-v2":
k, l, m, n = 256, 256, 384, 384
x = inputs
x_L_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_M_1 = Conv2D(filters=n, kernel_size=(3, 3), strides=2, padding='valid')(x)
x_R_1 = Conv2D(filters=k, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=l, kernel_size=(3, 3), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=m, kernel_size=(3, 3), strides=2, padding='valid')(x_R_2)
x = concatenate([x_L_1, x_M_1, x_R_3])
return x
def inception_resnet_v2_reduction_b_block(inputs,
names=None):
x = inputs
x_EL_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_ML_1 = Conv2D(filters=256, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ML_2 = Conv2D(filters=384, kernel_size=(3, 3), strides=2, padding='valid')(x_ML_1)
x_MR_1 = Conv2D(filters=256, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR_2 = Conv2D(filters=256, kernel_size=(3, 3), strides=2, padding='valid')(x_MR_1)
x_ER_1 = Conv2D(filters=256, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ER_2 = Conv2D(filters=256, kernel_size=(3, 3), strides=1, padding='same')(x_ER_1)
x_ER_3 = Conv2D(filters=256, kernel_size=(3, 3), strides=2, padding='valid')(x_ER_2)
x = concatenate([x_EL_1, x_ML_2, x_MR_2, x_ER_3])
return x
def create_inception_resnet_v2(inputShape=(imgrows, imgclms, channel),
num_classes=2):
NETWORK_SELECTED = "Inception-ResNet-v2"
inputs = Input(shape=inputShape)
x = stem_block(inputs)
x = inception_resnet_v2_a_block(x, scale=0.1)
x = inception_resnet_v2_a_block(x, scale=0.1)
x = inception_resnet_v2_a_block(x, scale=0.1)
x = inception_resnet_v2_a_block(x, scale=0.1)
x = inception_resnet_v2_a_block(x, scale=0.1)
x = reduction_a_block(x, network_selected=NETWORK_SELECTED)
x = inception_resnet_v2_b_block(x, scale=0.1)
x = inception_resnet_v2_b_block(x, scale=0.1)
x = inception_resnet_v2_b_block(x, scale=0.1)
x = inception_resnet_v2_b_block(x, scale=0.1)
x = inception_resnet_v2_b_block(x, scale=0.1)
x = inception_resnet_v2_b_block(x, scale=0.1)
x = inception_resnet_v2_b_block(x, scale=0.1)
x = inception_resnet_v2_b_block(x, scale=0.1)
x = inception_resnet_v2_b_block(x, scale=0.1)
x = inception_resnet_v2_b_block(x, scale=0.1)
x = inception_resnet_v2_reduction_b_block(x)
x = inception_resnet_v2_c_block(x, scale=0.1)
x = inception_resnet_v2_c_block(x, scale=0.1)
x = inception_resnet_v2_c_block(x, scale=0.1)
x = inception_resnet_v2_c_block(x, scale=0.1)
x = inception_resnet_v2_c_block(x, scale=0.1)
x = AveragePooling2D(pool_size=(1,1))(x) # Added (1,1) due to negative dimension
x = Flatten()(x)
x = Dense(1792)(x)
x = Dropout(0.2)(x)
outputs = Dense(num_classes, activation='softmax',
kernel_initializer='he_normal')(x)
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss='categorical_crossentropy',
optimizer="Adam",
metrics=['accuracy'])
return model
# Modified # Inception-Res-v2 -> func: create_inception_resnet_v2() 1,3,1 & 0.5
def stem_block(inputs,
names=None):
x = inputs
x = Conv2D(filters=32, kernel_size=(3, 3), strides=2, padding='valid')(inputs)
x = Conv2D(filters=32, kernel_size=(3, 3), strides=1, padding='valid')(x)
x = Conv2D(filters=64, kernel_size=(3, 3), strides=1, padding='same')(x)
x_L1_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_R1_1 = Conv2D(filters=96, kernel_size=(3, 3), strides=2, padding='valid')(x)
x = concatenate([x_L1_1, x_R1_1])
x_L2_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_L2_2 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(x_L2_1)
x_R2_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R2_2 = Conv2D(filters=64, kernel_size=(7, 1), strides=1, padding='same')(x_R2_1)
x_R2_3 = Conv2D(filters=64, kernel_size=(1, 7), strides=1, padding='same')(x_R2_2)
x_R2_4 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(x_R2_3)
x = concatenate([x_L2_2, x_R2_4])
x_L3_1 = Conv2D(filters=192, kernel_size=(3, 3), strides=2, padding='valid')(x)
x_L3_2 = ZeroPadding2D(padding=((0,1), (0,1)))(x_L3_1) # Added due to size mismatch
x_R3_1 = MaxPooling2D(strides=2, padding='valid')(x)
x = concatenate([x_L3_2, x_R3_1])
return x
def inception_resnet_v2_a_block(inputs,
scale=0.1,
names=None):
x = inputs
x_L_1 = Conv2D(filters=32, kernel_size=(1, 1), strides=1, padding='same')(x)
x_M_1 = Conv2D(filters=32, kernel_size=(1, 1), strides=1, padding='same')(x)
x_M_2 = Conv2D(filters=32, kernel_size=(3, 3), strides=1, padding='same')(x_M_1)
x_R_1 = Conv2D(filters=32, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=48, kernel_size=(3, 3), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=64, kernel_size=(3, 3), strides=1, padding='same')(x_R_2)
x_C_1 = concatenate([x_L_1, x_M_2, x_R_3])
x_C_2 = Conv2D(filters=384, kernel_size=(1, 1), padding='same', activation='linear')(x_C_1)
x = Lambda(lambda ipt, scale: ipt[0] + ipt[1] * scale,
output_shape=backend.int_shape(x)[1:],
arguments={'scale': scale})([x, x_C_2])
x = Activation(activation='relu')(x)
return x
def inception_resnet_v2_b_block(inputs,
scale=0.1,
names=None):
x = inputs
x_L_1 = Conv2D(filters=96, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=80, kernel_size=(1, 7), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=96, kernel_size=(7, 1), strides=1, padding='same')(x_R_2)
x_C_1 = concatenate([x_L_1, x_R_3])
x_C_2 = Conv2D(filters=672, kernel_size=(1, 1), padding='same', activation='linear')(x_C_1)
x = Lambda(lambda ipt, scale: ipt[0] + ipt[1] * scale,
output_shape=backend.int_shape(x)[1:],
arguments={'scale': scale})([x, x_C_2])
x = Activation(activation='relu')(x)
return x
def inception_resnet_v2_c_block(inputs,
scale=0.1,
names=None):
x = inputs
x_L_1 = Conv2D(filters=96, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_1 = Conv2D(filters=96, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=114, kernel_size=(1, 3), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=128, kernel_size=(3, 1), strides=1, padding='same')(x_R_2)
x_C_1 = concatenate([x_L_1, x_R_3])
x_C_2 = Conv2D(filters=1120, kernel_size=(1, 1), padding='same', activation='linear')(x_C_1)
x = Lambda(lambda ipt, scale: ipt[0] + ipt[1] * scale,
output_shape=backend.int_shape(x)[1:],
arguments={'scale': scale})([x, x_C_2])
x = Activation(activation='relu')(x)
return x
def reduction_a_block(inputs,
network_selected="Inception-v4",
names=None):
if network_selected == "Inception-v4":
k, l, m, n = 96, 112, 128, 192
elif network_selected == "Inception-ResNet-v1":
k, l, m, n = 96, 96, 128, 192
elif network_selected == "Inception-ResNet-v2":
k, l, m, n = 128, 128, 96, 192
x = inputs
x_L_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_M_1 = Conv2D(filters=n, kernel_size=(3, 3), strides=2, padding='valid')(x)
x_R_1 = Conv2D(filters=k, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=l, kernel_size=(3, 3), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=m, kernel_size=(3, 3), strides=2, padding='valid')(x_R_2)
x = concatenate([x_L_1, x_M_1, x_R_3])
return x
def inception_resnet_v2_reduction_b_block(inputs,
names=None):
x = inputs
x_EL_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_ML_1 = Conv2D(filters=128, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ML_2 = Conv2D(filters=192, kernel_size=(3, 3), strides=2, padding='valid')(x_ML_1)
x_MR_1 = Conv2D(filters=128, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR_2 = Conv2D(filters=128, kernel_size=(3, 3), strides=2, padding='valid')(x_MR_1)
x_ER_1 = Conv2D(filters=128, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ER_2 = Conv2D(filters=128, kernel_size=(3, 3), strides=1, padding='same')(x_ER_1)
x_ER_3 = Conv2D(filters=128, kernel_size=(3, 3), strides=2, padding='valid')(x_ER_2)
x = concatenate([x_EL_1, x_ML_2, x_MR_2, x_ER_3])
return x
def create_inception_resnet_v2(inputShape=(imgrows, imgclms, channel),
num_classes=2):
NETWORK_SELECTED = "Inception-ResNet-v2"
inputs = Input(shape=inputShape)
batch_norm = True
no_a_block = 1
no_b_block = 3
no_c_block = 1
x = stem_block(inputs)
for i in range(no_a_block):
if batch_norm == True:
x = BatchNormalization()(x)
x = inception_resnet_v2_a_block(x, scale=0.15)
x = BatchNormalization()(x)
x = reduction_a_block(x, network_selected=NETWORK_SELECTED)
for i in range(no_b_block):
if batch_norm == True:
x = BatchNormalization()(x)
x = inception_resnet_v2_b_block(x, scale=0.15)
x = BatchNormalization()(x)
x = inception_resnet_v2_reduction_b_block(x)
for i in range(no_c_block):
if batch_norm == True:
x = BatchNormalization()(x)
x = inception_resnet_v2_c_block(x, scale=0.15)
x = BatchNormalization()(x)
x = AveragePooling2D(pool_size=(1,1))(x) # Added (1,1) due to negative dimension
x = Flatten()(x)
x = Dense(896)(x)
x = Dropout(0.2)(x)
outputs = Dense(num_classes, activation='softmax',
kernel_initializer='he_normal')(x)
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss='categorical_crossentropy',
optimizer="Adam",
metrics=['accuracy'])
return model
# Modified # SE Inception-Res-v2 -> func: create_se_inception_resnet_v2() 1,3,1 & 0.5
def stem_block(inputs,
names=None):
x = inputs
x = Conv2D(filters=32, kernel_size=(3, 3), strides=2, padding='valid')(inputs)
x = Conv2D(filters=32, kernel_size=(3, 3), strides=1, padding='valid')(x)
x = Conv2D(filters=64, kernel_size=(3, 3), strides=1, padding='same')(x)
x_L1_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_R1_1 = Conv2D(filters=96, kernel_size=(3, 3), strides=2, padding='valid')(x)
x = concatenate([x_L1_1, x_R1_1])
x_L2_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_L2_2 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(x_L2_1)
x_R2_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R2_2 = Conv2D(filters=64, kernel_size=(7, 1), strides=1, padding='same')(x_R2_1)
x_R2_3 = Conv2D(filters=64, kernel_size=(1, 7), strides=1, padding='same')(x_R2_2)
x_R2_4 = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(x_R2_3)
x = concatenate([x_L2_2, x_R2_4])
x_L3_1 = Conv2D(filters=192, kernel_size=(3, 3), strides=2, padding='valid')(x)
x_L3_2 = ZeroPadding2D(padding=((0,1), (0,1)))(x_L3_1) # Added due to size mismatch
x_R3_1 = MaxPooling2D(strides=2, padding='valid')(x)
x = concatenate([x_L3_2, x_R3_1])
return x
def inception_resnet_v2_a_block(inputs,
scale=0.1,
names=None):
x = inputs
x_L_1 = Conv2D(filters=32, kernel_size=(1, 1), strides=1, padding='same')(x)
x_M_1 = Conv2D(filters=32, kernel_size=(1, 1), strides=1, padding='same')(x)
x_M_2 = Conv2D(filters=32, kernel_size=(3, 3), strides=1, padding='same')(x_M_1)
x_R_1 = Conv2D(filters=32, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=48, kernel_size=(3, 3), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=64, kernel_size=(3, 3), strides=1, padding='same')(x_R_2)
x_C_1 = concatenate([x_L_1, x_M_2, x_R_3])
x_C_2 = Conv2D(filters=384, kernel_size=(1, 1), padding='same', activation='linear')(x_C_1)
x = Lambda(lambda ipt, scale: ipt[0] + ipt[1] * scale,
output_shape=backend.int_shape(x)[1:],
arguments={'scale': scale})([x, x_C_2])
x = Activation(activation='relu')(x)
return x
def inception_resnet_v2_b_block(inputs,
scale=0.1,
names=None):
x = inputs
x_L_1 = Conv2D(filters=96, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_1 = Conv2D(filters=64, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=80, kernel_size=(1, 7), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=96, kernel_size=(7, 1), strides=1, padding='same')(x_R_2)
x_C_1 = concatenate([x_L_1, x_R_3])
x_C_2 = Conv2D(filters=672, kernel_size=(1, 1), padding='same', activation='linear')(x_C_1)
x = Lambda(lambda ipt, scale: ipt[0] + ipt[1] * scale,
output_shape=backend.int_shape(x)[1:],
arguments={'scale': scale})([x, x_C_2])
x = Activation(activation='relu')(x)
return x
def inception_resnet_v2_c_block(inputs,
scale=0.1,
names=None):
x = inputs
x_L_1 = Conv2D(filters=96, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_1 = Conv2D(filters=96, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=114, kernel_size=(1, 3), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=128, kernel_size=(3, 1), strides=1, padding='same')(x_R_2)
x_C_1 = concatenate([x_L_1, x_R_3])
x_C_2 = Conv2D(filters=1120, kernel_size=(1, 1), padding='same', activation='linear')(x_C_1)
x = Lambda(lambda ipt, scale: ipt[0] + ipt[1] * scale,
output_shape=backend.int_shape(x)[1:],
arguments={'scale': scale})([x, x_C_2])
x = Activation(activation='relu')(x)
return x
def reduction_a_block(inputs,
network_selected="Inception-v4",
names=None):
if network_selected == "Inception-v4":
k, l, m, n = 192, 224, 256, 384
elif network_selected == "Inception-ResNet-v1":
k, l, m, n = 96, 96, 128, 192
elif network_selected == "Inception-ResNet-v2":
k, l, m, n = 128, 128, 96, 192
x = inputs
x_L_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_M_1 = Conv2D(filters=n, kernel_size=(3, 3), strides=2, padding='valid')(x)
x_R_1 = Conv2D(filters=k, kernel_size=(1, 1), strides=1, padding='same')(x)
x_R_2 = Conv2D(filters=l, kernel_size=(3, 3), strides=1, padding='same')(x_R_1)
x_R_3 = Conv2D(filters=m, kernel_size=(3, 3), strides=2, padding='valid')(x_R_2)
x = concatenate([x_L_1, x_M_1, x_R_3])
return x
def inception_resnet_v2_reduction_b_block(inputs,
names=None):
x = inputs
x_EL_1 = MaxPooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)
x_ML_1 = Conv2D(filters=128, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ML_2 = Conv2D(filters=192, kernel_size=(3, 3), strides=2, padding='valid')(x_ML_1)
x_MR_1 = Conv2D(filters=128, kernel_size=(1, 1), strides=1, padding='same')(x)
x_MR_2 = Conv2D(filters=128, kernel_size=(3, 3), strides=2, padding='valid')(x_MR_1)
x_ER_1 = Conv2D(filters=128, kernel_size=(1, 1), strides=1, padding='same')(x)
x_ER_2 = Conv2D(filters=128, kernel_size=(3, 3), strides=1, padding='same')(x_ER_1)
x_ER_3 = Conv2D(filters=128, kernel_size=(3, 3), strides=2, padding='valid')(x_ER_2)
x = concatenate([x_EL_1, x_ML_2, x_MR_2, x_ER_3])
return x
def squeeze_excitation_layer(inputs, out_dim, ratio, layer_name):
x = inputs
x = GlobalAveragePooling2D()(x)
x = Dense(units=out_dim / ratio, use_bias=True)(x)
x = Activation(activation='relu')(x)
x = Dense(units=out_dim, use_bias=True)(x)
x = Activation(activation='sigmoid')(x)
x = Reshape([1, 1, out_dim])(x)
scale = Lambda(lambda ipt: ipt[0] * ipt[1] ,
output_shape=backend.int_shape(x)[1:])([inputs, x])
return scale
def create_se_inception_resnet_v2(inputShape=(imgrows, imgclms, channel),
num_classes=2):
NETWORK_SELECTED = "Inception-ResNet-v2"
inputs = Input(shape=inputShape)
batch_norm = True
no_a_block = 1
no_b_block = 3
no_c_block = 1
reduction_ratio = 4
x = stem_block(inputs)
for i in range(no_a_block):
if batch_norm == True:
x = BatchNormalization()(x)
x = inception_resnet_v2_a_block(x, scale=0.15)
chnl = int(np.shape(x)[-1])
x = squeeze_excitation_layer(x, out_dim=chnl, ratio=reduction_ratio, layer_name='SE_A'+str(i))
x = BatchNormalization()(x)
x = reduction_a_block(x, network_selected=NETWORK_SELECTED)
chnl = int(np.shape(x)[-1])
x = squeeze_excitation_layer(x, out_dim=chnl, ratio=reduction_ratio, layer_name='SE_A')
for i in range(no_b_block):
if batch_norm == True:
x = BatchNormalization()(x)
x = inception_resnet_v2_b_block(x, scale=0.15)
chnl = int(np.shape(x)[-1])
x = squeeze_excitation_layer(x, out_dim=chnl, ratio=reduction_ratio, layer_name='SE_B'+str(i))
x = BatchNormalization()(x)
x = inception_resnet_v2_reduction_b_block(x)
for i in range(no_c_block):
if batch_norm == True:
x = BatchNormalization()(x)
x = inception_resnet_v2_c_block(x, scale=0.15)
x = BatchNormalization()(x)
x = AveragePooling2D(pool_size=(1,1))(x) # Added (1,1) due to negative dimension
x = Flatten()(x)
x = Dense(896)(x)
x = Dropout(0.2)(x)
outputs = Dense(num_classes, activation='softmax',
kernel_initializer='he_normal')(x)
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss='categorical_crossentropy',
optimizer="Adam",
metrics=['accuracy'])
return model
# Setup the models
model = create_se_inception_resnet_v2() # This is meant for training
modelGo = create_se_inception_resnet_v2() # This is used for final testing
model.summary()
continue_training = True
if continue_training == True:
best_model_filepath = "FlowerPower_SEInceptionResNetV2best9429.hdf5"
model.load_weights(best_model_filepath)
# Create checkpoint for the training
# This checkpoint performs model saving when
# an epoch gives highest testing accuracy
# filepath = modelname + ".hdf5"
# checkpoint = ModelCheckpoint(filepath,
# monitor='val_acc',
# verbose=0,
# save_best_only=True,
# mode='max')
# # Log the epoch detail into csv
# csv_logger = CSVLogger(modelname +'.csv')
# callbacks_list = [checkpoint, csv_logger]
def lrSchedule(epoch):
lr = 1e-3
if epoch > 270: #190
lr *= 0.5e-3
elif epoch > 240: #160
lr *= 1e-3
elif epoch > 200: #140
lr *= 1e-2
elif epoch > 150: #100
lr *= 1e-1
print('Learning rate: ', lr)
return lr
LRScheduler = LearningRateScheduler(lrSchedule)
# Create checkpoint for the training
# This checkpoint performs model saving when
# an epoch gives highest testing accuracy
filepath = modelname + ".hdf5"
checkpoint = ModelCheckpoint(filepath,
monitor='val_acc',
verbose=0,
save_best_only=True,
mode='max')
# Log the epoch detail into csv
csv_logger = CSVLogger(modelname +'.csv')
callbacks_list = [checkpoint, csv_logger, LRScheduler]
# Fit the model
# This is where the training starts
# model.fit(trDat,
# trLbl,
# validation_data=(tsDat, tsLbl),
# epochs=60,
# batch_size=32,
# callbacks=callbacks_list)
datagen = ImageDataGenerator(width_shift_range=0.25,
height_shift_range=0.25,
rotation_range=45,
zoom_range=0.8,
#zca_epsilon=1e-6,
#zca_whitening=True,
fill_mode='nearest',
horizontal_flip=True,
vertical_flip=False)
model.fit_generator(datagen.flow(trDat, trLbl, batch_size=16),
validation_data=(tsDat, tsLbl),
epochs=300, #300
verbose=1,
steps_per_epoch=len(trDat)/16,
callbacks=callbacks_list)
##### Now the training is complete, we get
# another object to load the weights
# compile it, so that we can do
# final evaluation on it
modelGo.load_weights(filepath)
modelGo.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
# Make classification on the test dataset
predicts = modelGo.predict(tsDat)
# Prepare the classification output
# for the classification report
predout = np.argmax(predicts,axis=1)
testout = np.argmax(tsLbl,axis=1)
labelname = ['non-flower', 'flower']
# the labels for the classfication report
testScores = metrics.accuracy_score(testout,predout)
confusion = metrics.confusion_matrix(testout,predout)
print("Best accuracy (on testing dataset): %.2f%%" % (testScores*100))
print(metrics.classification_report(testout,predout,target_names=labelname,digits=4))
print(confusion)
import pandas as pd
records = pd.read_csv(modelname +'.csv')
plt.figure()
plt.subplot(211)
plt.plot(records['val_loss'])
plt.plot(records['loss'])
plt.yticks([0, 0.20, 0.30, 0.4, 0.5])
plt.title('Loss value',fontsize=12)
ax = plt.gca()
ax.set_xticklabels([])
plt.subplot(212)
plt.plot(records['val_acc'])
plt.plot(records['acc'])
plt.yticks([0.7, 0.8, 0.9, 1.0])
plt.title('Accuracy',fontsize=12)
plt.show()
wrong_ans_index = []
for i in range(len(predout)):
if predout[i] != testout[i]:
wrong_ans_index.append(i)
wrong_ans_index = list(set(wrong_ans_index))
# Randomly show X examples of that was wrong
dataset = tsDatOrg #flowers #fungus #rocks
for index in wrong_ans_index:
#index = wrong_ans_index[random.randint(0, len(wrong_ans_index)-1)]
print("Showing %s index image" %(index))
print("Predicted as %s but is actually %s" %(predout[index], testout[index]))
imgplot = plt.imshow(data[index])
plt.show()
modelGo1 = create_inception_v4() # This is used for final testing
modelGo1.load_weights("FlowerPower_InceptionV4best9470.hdf5")
modelGo1.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
modelGo2 = create_inception_resnet_v2() # This is used for final testing
modelGo2.load_weights("FlowerPower_InceptionResNetV2best9521.hdf5")
modelGo2.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
modelGo3 = create_se_inception_resnet_v2() # This is used for final testing
modelGo3.load_weights("FlowerPower_SEInceptionResNetV2best9489.hdf5")
modelGo3.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
predicts1 = modelGo1.predict(tsDat)
predicts2 = modelGo2.predict(tsDat)
predicts3 = modelGo3.predict(tsDat)
predicts_ave = []
weights = [0.33, 0.33, 0.33]
for i in range(len(predicts1)):
ave0 = predicts1[i][0]*weights[0] + predicts2[i][0]*weights[1] + predicts3[i][0]*weights[2]
ave1 = predicts1[i][1]*weights[0] + predicts2[i][1]*weights[1] + predicts3[i][1]*weights[2]
predicts_ave.append([ave0, ave1])
predicts_ave = np.array(predicts_ave)
# Prepare the classification output
# for the classification report
predout = np.argmax(predicts_ave,axis=1)
testout = np.argmax(tsLbl,axis=1)
labelname = ['non-flower', 'flower']
# the labels for the classfication report
testScores = metrics.accuracy_score(testout,predout)
confusion = metrics.confusion_matrix(testout,predout)
print("Best accuracy (on testing dataset): %.2f%%" % (testScores*100))
print(metrics.classification_report(testout,predout,target_names=labelname,digits=4))
print(confusion)
predicts_ave = []
weights = [0.30, 0.40, 0.30]
for i in range(len(predicts1)):
ave0 = predicts1[i][0]*weights[0] + predicts2[i][0]*weights[1] + predicts3[i][0]*weights[2]
ave1 = predicts1[i][1]*weights[0] + predicts2[i][1]*weights[1] + predicts3[i][1]*weights[2]
predicts_ave.append([ave0, ave1])
predicts_ave = np.array(predicts_ave)
# Prepare the classification output
# for the classification report
predout = np.argmax(predicts_ave,axis=1)
testout = np.argmax(tsLbl,axis=1)
labelname = ['non-flower', 'flower']
# the labels for the classfication report
testScores = metrics.accuracy_score(testout,predout)
confusion = metrics.confusion_matrix(testout,predout)
print("Best accuracy (on testing dataset): %.2f%%" % (testScores*100))
print(metrics.classification_report(testout,predout,target_names=labelname,digits=4))
print(confusion)
weights_all = []
for i in np.linspace(0, 0.5, 21):
for j in np.linspace(0, 0.5, 21):
weights_all.append([float(round(i,4)), float(round(j,4)), float(round(1-i-j,4))])
for weights in weights_all:
print(weights)
predicts_ave = []
for i in range(len(predicts1)):
ave0 = predicts1[i][0]*weights[0] + predicts2[i][0]*weights[1] + predicts3[i][0]*weights[2]
ave1 = predicts1[i][1]*weights[0] + predicts2[i][1]*weights[1] + predicts3[i][1]*weights[2]
predicts_ave.append([ave0, ave1])
predicts_ave = np.array(predicts_ave)
# Prepare the classification output
# for the classification report
predout = np.argmax(predicts_ave,axis=1)
testout = np.argmax(tsLbl,axis=1)
labelname = ['non-flower', 'flower']
# the labels for the classfication report
testScores = metrics.accuracy_score(testout,predout)
confusion = metrics.confusion_matrix(testout,predout)
print("Best accuracy (on testing dataset): %.2f%%" % (testScores*100))
print("\n")
# Best accuracy is obtained with the following weights:
# [0.35, 0.375, 0.275]
# Best accuracy (on testing dataset): 95.86%
predicts_ave = []
weights = [0.35, 0.375, 0.275]
for i in range(len(predicts1)):
ave0 = predicts1[i][0]*weights[0] + predicts2[i][0]*weights[1] + predicts3[i][0]*weights[2]
ave1 = predicts1[i][1]*weights[0] + predicts2[i][1]*weights[1] + predicts3[i][1]*weights[2]
predicts_ave.append([ave0, ave1])
predicts_ave = np.array(predicts_ave)
# Prepare the classification output
# for the classification report
predout = np.argmax(predicts_ave,axis=1)
testout = np.argmax(tsLbl,axis=1)
labelname = ['non-flower', 'flower']
# the labels for the classfication report
testScores = metrics.accuracy_score(testout,predout)
confusion = metrics.confusion_matrix(testout,predout)
print("Best accuracy (on testing dataset): %.2f%%" % (testScores*100))
print(metrics.classification_report(testout,predout,target_names=labelname,digits=4))
print(confusion)